﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using NetFramework;
using System.Net;

namespace GameServer
{
    public partial class Form1 : Form
    {
        private TSocketServer serversocket;
        private Dictionary<string, ListViewItem> m_dicViewItem = new Dictionary<string, ListViewItem>();
        private Dictionary<ListViewItem, ClientInfo> m_dicClientInfo = new Dictionary<ListViewItem, ClientInfo>();
        private ListViewItem m_currentSelectItem;

        public Form1()
        {
            InitializeComponent();
            FileManager.WriteBytes(@"d://hh\hh.txt","还打算开");
            List<string> lst = ServerDll.GetIpCpnfig();
            Console.WriteLine(lst);
            lbl_ip.Text = GetAddressIP();

            this.lvInfo.Scrollable = true;
            lvInfo.FullRowSelect = true;
            Control.CheckForIllegalCrossThreadCalls = false;
        }

        private void btnStarServer_Click(object sender, EventArgs e)
        {
            serversocket = new TSocketServer(1000, 2048);
            serversocket.Init();
            int port = 2048;
            serversocket.Start(port);
            serversocket.OnClientConnect += serversocket_OnClientConnect;
            serversocket.OnClientRead += new EventHandler<NetFramework.AsyncUserToken>(clientread);
            serversocket.OnClientDisconnect += new EventHandler<NetFramework.AsyncUserToken>(disconnect);

            this.btnStarServer.Enabled = false;
            this.btnStarServer.Text = "已启动";

            ServerDll.AddRouteHandel(MessageName.Login, ActionLogin);
            ServerDll.AddRouteHandel(MessageName.ClientCoin, OnClientCoin);
        }

        
        /// <summary>
        /// 新连接接入
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void serversocket_OnClientConnect(object sender, AsyncUserToken e)
        {
            string ip = e.EndPoint.Address.ToString();
            if (!ServerDll.BeIgnoreIp && !ServerDll.BeInLst(ip))
            {
                LoginResult(e.ConnectionId,false);
                serversocket.Disconnect(e.ConnectionId);
                Console.WriteLine( ip + "Do not in IpList");
            }
            ServerDll.ConnectClient(e);
            Console.WriteLine("Server " + e.ConnectionId);
        }

        /// <summary>
        /// 断开事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void disconnect(object sender, AsyncUserToken e)
        {
            RemoveViewItem(e.ConnectionId);
            ServerDll.DisconnectClient(e);
        }

        /// <summary>
        /// 消息接收处理
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="toker"></param>
        private void clientread(object sender, AsyncUserToken toker)
        {
            try
            {
                byte[] receiveData = new byte[toker.BytesReceived];
                Array.Copy(toker.ReceiveBuffer, toker.Offset, receiveData, 0, toker.BytesReceived);
                string message = System.Text.Encoding.UTF8.GetString(receiveData);
                ServerDll.DealMessage(toker.ConnectionId,message);
            }
            catch (Exception ex)
            {

                Console.WriteLine(ex.ToString());
            }
        }

        TSocketClient c;
        private void btnConnect_Click(object sender, EventArgs e)
        {
           
        }

        private void c_ReceivedDatagram(object sender, TSocketClientDataInEventArgs e)
        {
            
        }

        void c_OnConnected(object sender, TSocketClientConnectedEventArgs e)
        {
            Dictionary<string, object> message = new Dictionary<string, object>();
            message["route"] = MessageName.Login;
            message["ip"] = GetAddressIP();
            message["name"] = Dns.GetHostName();
            string s = Json.Serialize(message);
            byte [] bytess = System.Text.Encoding.UTF8.GetBytes(s);
            c.Send(bytess);
        }


        /// <summary>
        /// 获取本地IP地址信息
        /// </summary>
        string GetAddressIP()
        {
            ///获取本地的IP地址
            string addressIP = string.Empty;
            foreach (IPAddress _IPAddress in Dns.GetHostEntry(Dns.GetHostName()).AddressList)
            {
                if (_IPAddress.AddressFamily.ToString() == "InterNetwork")
                {
                    addressIP = _IPAddress.ToString();
                }
            }
            return addressIP;
        }

        private void btnSetting_Click(object sender, EventArgs e)
        {
            IpConfig ipForm = new IpConfig();
            ipForm.ShowDialog();
        }

        private void btnSetCoin_Click(object sender, EventArgs e)
        {
            if (m_currentSelectItem == null)
            {
                return ;
            }
            ClientInfo client = null;
            if (m_dicClientInfo.TryGetValue(m_currentSelectItem, out client))
            {
                m_currentSelectItem.SubItems[2].Text = this.tb_coin.Text;

                client.coinNum = ServerDll.GetInt(this.tb_coin.Text);
                SetClientCoin(client.connectedId, client.coinNum);
                MessageBox.Show("金币设置成功");
            }
        }

        private void lvInfo_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (this.lvInfo.SelectedItems.Count > 0)
            {
                ListViewItem lvi = this.lvInfo.SelectedItems[0];
                m_currentSelectItem = lvi;
                ClientInfo client = null;
                if (m_dicClientInfo.TryGetValue(lvi, out client))
                {
                    this.tb_coin.Text = client.coinNum.ToString();
                }
            }
        }

        private void SetViewItemCoin(ListViewItem lvi,int coin)
        {
            lvi.SubItems[2].Text = coin.ToString();
        }

        /// <summary>
        /// 移除ViewItem
        /// </summary>
        /// <param name="connectId"></param>
        private void RemoveViewItem(string connectId)
        {
            ListViewItem lvi = null;
            if (m_dicViewItem.TryGetValue(connectId, out lvi))
            {
                m_dicClientInfo.Remove(lvi);
                m_dicViewItem.Remove(connectId);
                lvi.Remove();
            }
        }

        #region 服务器报文
        /// <summary>
        /// 服务器向客户端发送报文
        /// </summary>
        /// <param name="connectionId"></param>
        /// <param name="coinNum"></param>
        private void SetClientCoin(string connectionId, int coinNum)
        {
            Dictionary<string, object> message = new Dictionary<string, object>();
            message["route"] = MessageName.ServerCoin;
            message["coin"] = coinNum;
            SendMessage(connectionId, message);
        }

        private void LoginResult(string connectionId, bool beSuccess)
        {
            Dictionary<string, object> message = new Dictionary<string, object>();
            message["route"] = MessageName.LoginResult;
            message["besuccess"] = beSuccess;
            if (beSuccess)
            {
                message["data"] = FruitDataManager.Intstance.GetSaveStr();
            }
            SendMessage(connectionId, message);
        }

        /// <summary>
        /// 服务器发送报文
        /// </summary>
        /// <param name="connectionId"></param>
        /// <param name="message"></param>
        private void SendMessage(string connectionId, Dictionary<string, object> message)
        {
            string messageStr = Json.Serialize(message);
            byte[] bytes = System.Text.Encoding.UTF8.GetBytes(messageStr);
            serversocket.Send(connectionId, bytes);
        }

        #endregion

        #region 客户端登录函数
        /// <summary>
        /// 客户端登录
        /// </summary>
        /// <param name="connectedId"></param>
        /// <param name="message"></param>
        public void ActionLogin(string connectedId, Dictionary<string, object> message)
        {
            ClientInfo client = ServerDll.GetClientById(connectedId);
            client.clientName = DictionaryUnity.GetSafeStringValue(message, "name");
            client.coinNum = DictionaryUnity.GetSafeIntValue(message, "coin");
            if (!m_dicViewItem.ContainsKey(connectedId))
            {
                ListViewItem lvi = new ListViewItem();
                m_dicViewItem[connectedId] = lvi;
                m_dicClientInfo[lvi] = client;
                lvi.Text = client.ipAddress;
                lvi.SubItems.Add(client.clientName);
                lvi.SubItems.Add(client.coinNum.ToString());
                this.lvInfo.Items.Add(lvi);
            }
            LoginResult(connectedId, true);
        }

        /// <summary>
        /// 客户端设置金币
        /// </summary>
        /// <param name="connectedId"></param>
        /// <param name="message"></param>
        private void OnClientCoin(string connectedId, Dictionary<string, object> message)
        {
            ClientInfo client = ServerDll.GetClientById(connectedId);
            client.coinNum = DictionaryUnity.GetSafeIntValue(message, "coin");

            ListViewItem lvi = null;
            if (m_dicViewItem.TryGetValue(connectedId, out lvi))
            {
                SetViewItemCoin(lvi, client.coinNum);
            }
        }

        #endregion
    }
}
